---
title: "Backend Actions & Agents"
description: "Learn how to enable your Copilot to take actions in the backend."
---

<Steps>
<Step>
### Find your CopilotRuntime

The starting point for backend actions is the `CopilotRuntime` you setup during quickstart (the CopilotKit backend endpoint).
For a refresher, see [Self-Hosting](/guides/self-hosting) (or alternatively, revisit the [quickstart](/quickstart)).

Backend actions can return (and stream) values -- which will be piped back to the Copilot system and which may result in additional agentic action.
</Step>

<Step>
### Integrate your backend actions

Choose any of the methods below to integrate backend actions into your Copilot system.<br/>
**They can be mixed-and-matched as desired.**

<Tabs items={['TypeScript / Node.js', 'LangChain JS', 'LangServe', 'Python + Remote Actions']}>


  {/* Native Backend Action tab */}
  <Tab value="TypeScript / Node.js">

  When you initialize the `CopilotRuntime`, you can provide backend actions in the same format as frontend Copilot actions.

  **Note that `actions` is not merely an array of actions, but rather a _generator_ of actions.**
  This generator takes `properties` and `url` as input -- which means you can customize which backend actions are made available according to the current frontend URL,
  as well as custom properties you can pass from the frontend.

    ```tsx title="/api/copilotkit/route.ts"
    const runtime = new CopilotRuntime({
      actions: ({properties, url}) => {
        // You can use the input parameters to the actions generator to expose different backend actions to the Copilot at different times: 
        // `url` is the current URL on the frontend application.
        // `properties` contains custom properties you can pass from the frontend application.
        
        return [
          {
            name: "fetchNameForUserId",
            description: "Fetches user name from the database for a given ID.",
            parameters: [
              {
                name: "userId",
                type: "string",
                description: "The ID of the user to fetch data for.",
                required: true,
              },
            ],
            handler: async ({userId}: {userId: string}) => {
              // do something with the userId
              // return the user data
              return {
                name: "Darth Doe",
              };
            },
          },
        ]
      }
    });

    // ... define the route using the CopilotRuntime.
    ```
  </Tab>

  {/* LangChain JS Backend Action tab */}
  <Tab value="LangChain JS">
  The backend action interface also supports LangChain JS natively.
  Simply return chain.stream and the results will be piped back to the Copilot.

    ```tsx title="/api/copilotkit/route.ts"
    import { ChatOpenAI } from "@langchain/openai";
    import { ChatPromptTemplate } from "@langchain/core/prompts";

    const runtime = new CopilotRuntime({
      actions: ({properties, url}) => {
        return [
          {
            name: "generateJokeForTopic",
            description: "Generates a joke for a given topic.",
            parameters: [
              {
                name: "topic",
                type: "string",
                description: "The topic to generate a joke about.",
                required: true,
              },
            ],
            handler: async ({topic}: {topic: string}) => {
              const prompt = ChatPromptTemplate.fromMessages([
                [
                  "system",
                  "You are a witty comedian. Generate a short, funny joke about the given topic. But make it sound like a pirate joke!",
                ],
                ["user", "Topic: {topic}"],
              ]);
              const chain = prompt.pipe(new ChatOpenAI());
              return chain.stream({
                topic: topic,
              });
            },
          },
        ]
      }
    });
    ```
  </Tab>

    {/* LangServe tab */}
  <Tab value="LangServe">
    LangServe allows you to integrate LangChain chains hosted as separate services into your CopilotKit application.
    You can easily connect to existing chains, whether they're written in Python or JavaScript.

    ```tsx title="/api/copilotkit/route.ts"
    const runtime = new CopilotRuntime({
      langserve: [
        {
          chainUrl: "http://my-langserve.chain",
          name: "performResearch",
          description: "Performs research on a given topic.",
        },
      ],
    });

    // ... define the route using the CopilotRuntime.
    ```

  </Tab>


  {/* Remote Actions tab */}
  <Tab value="Python + Remote Actions">
    Remote actions allow you to integrate external services or APIs into your CopilotKit application.
    Any service that conforms to the Open-Source CopilotKit backend protocol can be served here.

    We provide a Python backend SDK which includes support for [LangGraph-powered CoAgents!](/coagents).
    For instructions how to set it up, see [here]().

    ```tsx title="/api/copilotkit/route.ts"
    const runtime = new CopilotRuntime({
      remoteEndpoints: [
        {
          url: `${BASE_URL}/copilotkit`,
        },
      ],
    });

    // ... define the route using the CopilotRuntime.
    ```

  </Tab>

</Tabs>

</Step>

<Step>
### Test it out!
After defining the action, ask the copilot to perform the task. Watch it select the correct task, execute it, and stream back relevant responses.
</Step>
</Steps>
